
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#include "apr-1/apr_pools.h"
#include "apr-1/apr_general.h"
#include "apr-1/apr_file_io.h"
#include "apr-1/apr_file_info.h"
#include "apr-1/apr_network_io.h"
#include "apr-1/apr_errno.h"
#include "apr-1/apr_poll.h"
#include "apr-1/apr_lib.h"
#include "apr-1/apr_strings.h"
#include "apr-1/apr_thread_proc.h"

#include "map.h"

apr_pool_t *gpool;

map2_t map2;
uint32_t pins[10000];

void initialize(void) {
    apr_initialize();
    apr_pool_create(&gpool, NULL);
}
void test_search(void);

static int select_filter_1(const void* c, map2_item_t* item){
    if(item->flag){
        return 1;
    }
    return 0;
}

static int select_filter_2(const void* c, map2_item_t* item){
    uint32_t index = (unsigned long long)c;
    if(index == item->index){
        return 1;
    }
    return 0;
}

int main(int argc, char**argv){
    int ret;
    printf("Hello, from map!\n");
    // test_search();
    char path[256];
    printf("cwd: %s\n", getcwd(path, sizeof(path)));
    initialize();
    ret = map2_setup2(&map2, "pin", sizeof(uint32_t));
    if(ret){
        printf("map2_setup: %d", ret);
        return -1;
    }
    uint32_t n = 100;
    for(uint32_t i = 0; i < 100; i++){
         pins[i] = n--;
    }
    int a = 0, b = 100 - 1;
    while(a < b){
        uint32_t t = pins[a];
        pins[a] = pins[b];
        pins[b] = t;
        a += 2;
        b -= 2;
    }
    for(uint32_t i = 0; i < 100; i++){
        map2_add2(&map2, &pins[i], 4, i);
    }
    uint32_t pin = 21;
    uint8_t buf[64] = {0};
    map2_item_t* item = (map2_item_t*)buf;
    int pos = map2_search2(&map2, &pin, item);
    if(pos < 0 ){
        printf("search fail: %d\n", pos);
    }
    else{
         printf("pin(%d) at: %d flag = %d\n", pin, item->index, item->flag);
    }

    if(pos >= 0){
        printf("delete pin: %d\n", pin);
        map2_delete2(&map2, item->kval);
    }
    pos = map2_search2(&map2, &pin, item);
    if(pos < 0 ){
        printf("search fail: %d\n", pos);
    }
    else{
        printf("pin(%d) at: %d flag = %d\n", pin, item->index, item->flag);
    }
    /*===============================================================================*/
    map2_clear(&map2);
    uint32_t index = 0;
    for(int i = 0; i < 100; i++){
        map2_add2(&map2, &pins[i], sizeof(uint32_t), index ++);
    }
    for(int i = 0; i < 100; i++){
        map2_add2(&map2, &pins[i], sizeof(uint32_t), index ++);
    }
    {
        select_cond_t cond = {
            .cond = NULL,
            .key = &pin,
            .limit = 2,
            .filter = select_filter_1,
        };
        select_result_t result;
        map2_select(&map2, &cond, &result);
        for(int i = 0; i < result.count; i++){
            select_item_t* si = result.items[i];
            printf("pin(%d) at: %d flag = %d fnum = %d, pos = %d\n", pin, si->index, si->flag, si->fnum, si->pos);
        }
        map2_select_result_clean(&result);
    }
    {
        select_cond_t cond = {
            .cond = (void*)20,
            .key = &pin,
            .limit = 1,
            .filter = select_filter_2,
        };
        select_result_t result;
        map2_select(&map2, &cond, &result);
        select_item_t* si = NULL;
        for(int i = 0; i < result.count; i++){
            si = result.items[i];
            printf("pin(%d) at: %d flag = %d fnum = %d, pos = %d\n", pin, si->index, si->flag, si->fnum, si->pos);
        }
        //删除
        if(si){
            map2_update(&map2, si->fnum, si->pos, &pin, si->index, 0);
        }
        map2_select_result_clean(&result);
        map2_select(&map2, &cond, &result);
        for(int i = 0; i < result.count; i++){
            si = result.items[i];
            printf("pin(%d) at: %d flag = %d fnum = %d, pos = %d\n", pin, si->index, si->flag, si->fnum, si->pos);
        }
        map2_select_result_clean(&result);
    }
    return 0;
}
